package twoD.Csg;

import inf.jlinalg.ArrayVector;
import inf.jlinalg.BLAM;
import inf.jlinalg.IMatrix;
import inf.jlinalg.IVector;

public abstract class Primitive implements IPrimitive {

	protected static final double TOL = 1e-14;
	private Transformation T;

	public Primitive() {
		T = new Transformation();
	}

	/**
	 * set the transformation for this primitive. As a rule, access to location
	 * of this primitive will have to refer to transformation. The data provided
	 * in constructor is the reference of primitive in original location
	 * 
	 * @param T
	 */
	@Override
	public void setTransformation(Transformation T) {
		this.T = T;
	}

	@Override
	public Transformation getTransformation() {
		return T;
	}

	/**
	 * consider p is the point after applying transformation. This function find
	 * the original location of p. For example, when one want to check the
	 * location of p in the primitive. He have to transform p into original
	 * location w.r.t to the original primitive in order to check for location
	 * 
	 * @param p
	 * @return the inverse location vector
	 */
	public IVector getInverseLocation(double... p) {
		int n = p.length;
		IVector ptilde = new ArrayVector(n + 1);
		for (int i = 0; i < n; i++)
			ptilde.set(i, p[i]);
		ptilde.set(n, 1);
		if (T.getH() != null) {
			IMatrix H1 = T.getH1();
			IVector phat = (IVector) ptilde.clone();
			BLAM.multiply(1, BLAM.NO_TRANSPOSE, H1, ptilde, 0, phat);
			return phat;
		} else
			return ptilde;
	}
}
